package com.newflypig.jblog.service.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.newflypig.jblog.dao.BaseDAO;
import com.newflypig.jblog.model.Pager;
import com.newflypig.jblog.service.BaseService;
import com.newflypig.jblog.util.BlogConfig;

/**
 *  公用服务类，实现大多数常用操作
 *	@author newflypig
 *	time：2015年11月23日
 *
 */
public abstract class BaseServiceImpl<T extends Serializable> implements BaseService<T> {

	protected abstract BaseDAO<T> getDao();
	
	private Class<T> entityClazz;
	 
    public BaseServiceImpl() {        
        resovleClazzInfo();
    }
     
	@SuppressWarnings("unchecked")
	private void resovleClazzInfo() {
        Type genType = getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        entityClazz = (Class<T>) params[0];
    }
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void save(T entity) {
		this.getDao().save(entity);
	}
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void delete(T entity) {
		this.getDao().delete(entity);
	}
	
	@Override
	@Transactional(propagation=Propagation.NEVER)
	public T findById(Integer id) {
		return this.getDao().findById(id);
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void update(T entity) {
		this.getDao().update(entity);
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void deleteById(Integer id) {
		this.getDao().deleteById(id);
	}
	
	@Override
	@Transactional(propagation=Propagation.NEVER)
	public List<T> findAll() {
		return this.getDao().findAll();
	}
	
	@Override
	@Transactional(propagation=Propagation.NEVER)
	public Pager<T> generatePage(DetachedCriteria dc,DetachedCriteria dc2,Integer page) {
		Pager<T> pagerT=new Pager<T>();
		
		//向上取整得到总页数
		int totalPages=(int) Math.ceil((double)this.getDao().getCount(dc2)/BlogConfig.getNumberPerPage(entityClazz));
		pagerT.setTotalSize(totalPages);
		
		//如果传参page为空，则需要初始化page
		if(page==null){
			switch(this.entityClazz.getSimpleName()){
			case "Article":
				page=1;
				break;
			case "Comment":
				page=totalPages;
				break;
			default:
				page=1;
			}
		}
		
		//根据dc，查询数据库，给出数据
		pagerT.setData(this.getDao().findPager(dc,page));
		if(pagerT.getData().size()==0)
			return null;
		
		//设置当前页
		pagerT.setCurrentPage(page);
		
		//分页逻辑
		List<String[]> urls=new ArrayList<String[]>();
		if(page==1 && totalPages>1)
			urls.add(new String[]{"下一页","2"});
		else if(page==1){}
		else{
			urls.add(new String[]{"首页",String.valueOf(1)});
			urls.add(new String[]{"上一页",String.valueOf(page-1)});
			int eage=BlogConfig.getNumberShowPage(entityClazz)/2;
			int min=1;int max=totalPages;
			min=Math.max(min, page-eage);
			if(page+eage>totalPages && min-(page+eage-totalPages)>0)
				min=min-(page+eage-totalPages);
			max=Math.min(max, page+eage);
			if(page-eage<1 && max+((eage+1)-page)<=totalPages)
				max=max+eage+1-page;
			for(int i=min;i<=max;i++)
				urls.add(new String[]{String.valueOf(i),String.valueOf(i)});			
			if(page!=totalPages){
				urls.add(new String[]{"下一页",String.valueOf(page+1)});
				urls.add(new String[]{"尾页",String.valueOf(totalPages)});
			}
		}
		pagerT.setUrls(urls);
		return pagerT;
	}
}
